package server.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import model.Usuario;
import server.exception.DAOException;
import server.exception.ServiceException;
import server.model.Penalizacion;

public class PenalizacionesDAO {
	private static Connection conexion;
	
	public PenalizacionesDAO (){
		if(PenalizacionesDAO.conexion == null)
			PenalizacionesDAO.conexion = ConexionDAO.getInstance();
	}

	/**
	 * Obtiene una penalizacion identificada por id
	 * 
	 * @param id
	 *            Identificador de la penalizacion
	 * @return Penalizacion identificada por ID
	 * @throws ServiceException
	 *             En caso de no poder completarse la accion
	 */
	public Penalizacion obtener(int id) throws DAOException {
		try {
			String sql = "select * from penalizaciones "
					+ "where id_penalizacion = " + id + ";";
			Statement st = conexion.createStatement();
			ResultSet rs = st.executeQuery(sql);
			Usuario user = new Usuario();
			user.setNick(rs.getString("nick"));
			Penalizacion penalizacion = new Penalizacion();
			penalizacion.setId(id);
			penalizacion.setUsuario(user);
			penalizacion.setMotivo(rs.getString("motivo"));
			penalizacion.setInicio(rs.getTimestamp("inicio"));
			penalizacion.setFin(rs.getTimestamp("fin"));
			return penalizacion;
		} catch (SQLException e) {
			throw new DAOException("no se puede realizar la accion", e);
		}
	}

	/**
	 * Penaliza un usuario
	 * 
	 * @param usuario
	 *            Usuario que sera penalizado
	 * @param motivo
	 *            Motivo por el cual se lo penaliza
	 * @param hastaCuando
	 *            Fecha limite hasta la que se mantendra la penalizacion
	 * @return true en caso de exito, false en caso contrario
	 * @throws ServiceException
	 *             En caso de no poder completarse la accion
	 */
	public boolean penalizar(Usuario usuario, String motivo,
			Calendar hastaCuando) throws DAOException {
		try {
			String sql = "insert into penalizaciones "
					+ "(id_usuario, motivo, fecha_inicio, fecha_fin) "
					+ "values(?,?,?,?);";
			PreparedStatement pst = conexion.prepareStatement(sql);
			pst.setInt(1, usuario.getId());
			pst.setString(2, motivo);
			pst.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
			pst.setTimestamp(4, new Timestamp(hastaCuando.getTimeInMillis()));
			return true;
		} catch (SQLException e) {
			throw new DAOException("no se pudo realizar la accion", e);
		}
	}

	/**
	 * Penaliza un usuario
	 * 
	 * @param usuario
	 *            Usuario que sera penalizado
	 * @param motivo
	 *            Motivo por el cual se lo penaliza
	 * @param dias
	 *            Cantidad de dias que se mantendra la penalizacion
	 * @return true en caso de exito, false en caso contrario
	 * @throws ServiceException
	 *             En caso de no poder completarse la accion
	 */
	public boolean penalizar(Usuario usuario, String motivo, int dias)
			throws DAOException {
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DATE, dias);
			String sql = "insert into penalizaciones "
					+ "(id_usuario, motivo, fecha_inicio, fecha_fin) "
					+ "values(?,?,?,?);";
			PreparedStatement pst = conexion.prepareStatement(sql);
			pst.setInt(1, usuario.getId());
			pst.setString(2, motivo);
			pst.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
			pst.setTimestamp(4, new Timestamp(calendar.getTimeInMillis()));
			return pst.executeUpdate() == 1;
		} catch (SQLException e) {
			throw new DAOException("no se pudo realizar la accion", e);
		}
	}

	/**
	 * Penaliza un usuario
	 * 
	 * @param penalizacion
	 *            Objeto que contiene los datos para penalizar
	 * @return true en caso de exito, false en caso contrario
	 * @throws ServiceException
	 *             En caso de no poder completarse la accion
	 */
	public boolean penalizar(Penalizacion penalizacion) throws DAOException {
		try {
			String sql = "insert into penalizaciones "
					+ "(id_usuario, motivo, fecha_inicio, fecha_fin) "
					+ "values(?,?,?,?);";
			PreparedStatement pst = conexion.prepareStatement(sql);
			pst.setInt(1, penalizacion.getUsuario().getId());
			pst.setString(2, penalizacion.getMotivo());
			pst.setTimestamp(3, penalizacion.getInicio());
			pst.setTimestamp(4, penalizacion.getFin());
			conexion.commit();
			return true;
		} catch (SQLException e) {
			throw new DAOException("no se pudo realizar la accion", e);
		}
	}

	/**
	 * Obtiene una lista de todas las penalizaciones activas
	 * 
	 * @return Lista de penalizaciones activas
	 * @throws ServiceException
	 *             En caso de no poder concretarse la accion
	 */
	public List<Penalizacion> todas() throws DAOException {
		List<Penalizacion> listaPenalizados = new ArrayList<Penalizacion>();
		try {
			Usuario user = null;
			String sql = "select * from penalizaciones;";
			Statement st = conexion.createStatement();
			ResultSet rs = st.executeQuery(sql);
			while (rs.next()) {
				user = new Usuario();
				user.setNick(rs.getString("nick"));
				Penalizacion penalizacion = new Penalizacion();
				penalizacion.setId(rs.getInt("id_penalizacion"));
				penalizacion.setUsuario(user);
				penalizacion.setMotivo(rs.getString("motivo"));
				penalizacion.setInicio(rs.getTimestamp("inicio"));
				penalizacion.setFin(rs.getTimestamp("fin"));
				listaPenalizados.add(penalizacion);
			}

		} catch (SQLException e) {
			throw new DAOException("no se puede realizar la accion", e);
		}
		return listaPenalizados;
	}

	/**
	 * Obtiene una lista con todas las penalizaciones vencidas, es decir las que
	 * ya paso la fecha limite
	 * 
	 * @return Lista de penalizaciones vencidas
	 * @throws ServiceException
	 *             En caso de no poder concretarse la accion
	 */
	public List<Penalizacion> vencidas() throws DAOException {
		List<Penalizacion> listaPenalizaciones = new ArrayList<Penalizacion>();
		try {
			String sql = "select * from penalizaciones " + "where fin < "
					+ System.currentTimeMillis() + ";";
			Statement st = conexion.createStatement();
			ResultSet rs = st.executeQuery(sql);
			while (rs.next()) {
				Usuario user = new Usuario();
				user.setNick(rs.getString("nick"));
				Penalizacion penalizacion = new Penalizacion();
				penalizacion.setUsuario(user);
				penalizacion.setMotivo(rs.getString("motivo"));
				penalizacion.setInicio(rs.getTimestamp("inicio"));
				penalizacion.setFin(rs.getTimestamp("fin"));
				listaPenalizaciones.add(penalizacion);
			}
			return listaPenalizaciones;
		} catch (SQLException e) {
			throw new DAOException("no se puede realizar la accion", e);
		}
	}

	/**
	 * Elimina una penalizacion
	 * 
	 * @param penalizacion
	 *            Penalizacion a eliminar
	 * @return true en caso de exito, false en caso contrario
	 * @throws DAOException
	 *             En caso de no poder concretarse la accion
	 */
	public boolean eliminar(Penalizacion penalizacion) throws DAOException {
		try {
			String sql = "UPDATE penalizaciones " + "set fin = "
					+ System.currentTimeMillis() + "where id_penalizacion = "
					+ penalizacion.getId() + "AND id_usuario = "
					+ penalizacion.getUsuario().getId() + ";";
			Statement st = conexion.createStatement();
			st.executeQuery(sql);
			return true;
		} catch (SQLException e) {
			throw new DAOException("no se pudo realizar la accion", e);
		}
	}

	/**
	 * Verifica si un usuario esta penalizado
	 * 
	 * @param usuario
	 *            Usuario que se desea consultar si esta penalizado
	 * @return Objeto Penalizacion que contiene los datos de la penalizacion,
	 *         null en caso de no estar penalizado
	 * @throws ServiceException
	 *             En caso de no poder concretarse al accion
	 */
	public Penalizacion penalizado(Usuario usuario) throws DAOException {
		try {
			String sql = "select * from penalizaciones "
						+"where id_usuario = " + usuario.getId() + ";";
			Statement st = conexion.createStatement();
			ResultSet rs = st.executeQuery(sql);
			Usuario user = new Usuario();
			user.setNick(rs.getString("nick"));
			Penalizacion penalizacion = new Penalizacion();
			penalizacion.setId(usuario.getId());
			penalizacion.setUsuario(user);
			penalizacion.setMotivo(rs.getString("motivo"));
			penalizacion.setInicio(rs.getTimestamp("inicio"));
			penalizacion.setFin(rs.getTimestamp("fin"));
			return penalizacion;
		} catch (SQLException e) {
			throw new DAOException("no se puede realizar la accion", e);
		}
	}

	public List<Penalizacion> buscar(Penalizacion ejemplo) {
		// TODO Auto-generated method stub
		return null;
	}

}
